﻿using commodity.Database;
using commodity.Dtos;
using commodity.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace commodity.Services
{
    public class CommodityRepository : ICommodityRepository
    {
        private CommodityDbContext _commodityDbContext;
        public CommodityRepository(CommodityDbContext context)
        {
            _commodityDbContext = context;
        }

        public async Task addCateFromByCateFromAsync(AddCateFromDto addCateFromDto)
        {
            switch (addCateFromDto.Cat_level) 
            {
                case 0: 
                    {
                        _commodityDbContext.FirstsCommodityMenus.Add(new FirstsCommodityMenu() { Name = addCateFromDto.Cat_Name });
                        break;
                    }
                case 1:
                    {
                        _commodityDbContext.SecondCommodityMenus.Add(new SecondCommodityMenu() { Name = addCateFromDto.Cat_Name, FirstsCommodityMenuId=addCateFromDto.Cat_Pid });
                        break;
                    }
                case 2: 
                    {
                      var data =await _commodityDbContext.SecondCommodityMenus.SingleOrDefaultAsync(u => u.Id == addCateFromDto.Cat_Pid);
                        _commodityDbContext.Set<Commodity>().Add(new Commodity { CommodityName = addCateFromDto.Cat_Name, SecondCommodityMenuCommodities = new List<SecondCommodityMenuCommodity> { new SecondCommodityMenuCommodity {secondCommodityMenu=data,SecondCommodityMenuId=data.Id } } });
                        break;
                    }
            }
        }

        public void AddCommodityInformation(CommodityInformation commodityInformation)
        {
            _commodityDbContext.CommodityInformations.Add(commodityInformation);
        }

        public async Task<bool> AddGoods(Goods goods)
        {
            _commodityDbContext.Add(goods);
            return (await _commodityDbContext.SaveChangesAsync() >= 0);
        }

        public async Task<bool> CommodityExistsByCommodityIdAsync(int CommodityId)
        {
            return await _commodityDbContext.Commodities.AnyAsync(u => u.id == CommodityId);
        }

        public async Task<bool> CommodityInformationExistsAsync(int CommodityId, int CommodityInformationId)
        {
            return await _commodityDbContext.CommodityInformations.AnyAsync(u => u.CommodityId == CommodityId && u.id == CommodityInformationId);
        }

        public async Task DeleteCommodityInformationByInformationId(int InformationId)
        {
            CommodityInformation commodityInformation = await _commodityDbContext.CommodityInformations.SingleOrDefaultAsync(u => u.id == InformationId);
            _commodityDbContext.Entry(commodityInformation).State = EntityState.Deleted;
        }

        public async Task<bool> DeleteGoodsByGoodId(int goodId)
        {
            try
            {
                Goods goods = await _commodityDbContext.goods.SingleAsync(u => u.Goods_Id == goodId);
                _commodityDbContext.Entry(goods).State = EntityState.Deleted;
                return true;
            }
            catch {
                return false;
            }
        }

        public void EditCommodityInformationByInformationDto(CommodityInformation commodityInformation)
        {
            _commodityDbContext.Entry(commodityInformation).State = EntityState.Modified;
        }

        public async Task<IEnumerable<FirstsCommodityMenu>> GetAllData(int? type)
        {

            if (type == null)
            {
                IEnumerable<FirstsCommodityMenu> firstsCommodityMenus = await _commodityDbContext.FirstsCommodityMenus.Include(u => u.SecondCommodityMenus).ThenInclude(u => u.SecondCommodityMenuCommodities).ThenInclude(u => u.Commodity).Where(u => u.Id > 0).ToListAsync();
                return firstsCommodityMenus;
            }
            else
            {
                switch (type)
                {
                    case 1:
                        {
                            IEnumerable<FirstsCommodityMenu> firstsCommodityMenus = await _commodityDbContext.FirstsCommodityMenus.Where(u => u.Id > 0).ToListAsync();
                            return firstsCommodityMenus;

                        }
                    case 2:
                        {
                            IEnumerable<FirstsCommodityMenu> firstsCommodityMenus = await _commodityDbContext.FirstsCommodityMenus.Include(u => u.SecondCommodityMenus).Where(u => u.Id > 0).ToListAsync();
                            return firstsCommodityMenus;
                        }
                    default:
                        {
                            IEnumerable<FirstsCommodityMenu> firstsCommodityMenus = await _commodityDbContext.FirstsCommodityMenus.Include(u => u.SecondCommodityMenus).ThenInclude(u => u.SecondCommodityMenuCommodities).ThenInclude(u => u.Commodity).Where(u => u.Id > 0).ToListAsync();
                            return firstsCommodityMenus;
                        }
                }
            }
        }

        public async Task<IEnumerable<CommodityInformation>> GetCommodityInformationByIdAsync(int id, int state)
        {
            return await _commodityDbContext.CommodityInformations.Where(u => u.CommodityId == id && (int)u.state == state).ToListAsync();
        }

        public async Task<IEnumerable<Goods>> GetGoods(GetGoodsDto getGoodsDto)
        {
            if (string.IsNullOrWhiteSpace(getGoodsDto.Query)) 
            {
                return await _commodityDbContext.goods.Skip((getGoodsDto.Pagenum - 1) * getGoodsDto.PageSize).Take(getGoodsDto.PageSize).Where(u => u.Goods_Id > 0).ToListAsync(); 
            }
            return await _commodityDbContext.goods.Skip((getGoodsDto.Pagenum - 1) * getGoodsDto.PageSize).Take(getGoodsDto.PageSize).Where(u => u.Goods_Name.Contains(getGoodsDto.Query)).ToListAsync();
        }

        public async Task<int> GetGoodsTotal()
        {
            return await _commodityDbContext.goods.CountAsync(u => u.Goods_Id > 0);
        }

        public async Task<CommodityInformation> GetInformationByInformationId(int InformationId)
        {
            return await _commodityDbContext.CommodityInformations.Include(u => u.commodity).SingleOrDefaultAsync(u=>u.id==InformationId);
        }

        public async Task<bool> SaveAsync()
        {
            return (await _commodityDbContext.SaveChangesAsync() >= 0);
        }
        
    }
}

